--
-- Author: dbliu
-- Date: 2014-02-26 20:17:05
--
--=model=========================================================================================================
--local EMPlayer = import(".EMPlayer")
local EM = import("..EM")
local EMPlayer = class("EMPlayer", EM)
local scheduler = require(cc.PACKAGE_NAME .. ".scheduler")

-- 定义事件
EMPlayer.START_EVENT = "START_EVENT"
EMPlayer.KILL_EVENT = "KILL_EVENT"

EMPlayer.schema = clone(EM.schema)

function EMPlayer:ctor(properties, events, callbacks)

	local defaultEvents = {
		-- 开火
        {name = "fire",   from = "idle",    to = "firing"},
        -- 开火冷却结束
        {name = "fire_finish",  from = "firing",  to = "idle"},
		--填充子弹
		{name = "reload_bullet", from = "idle",    to = "loading_bullet"},
		--填充子弹完毕
		{name = "reload_bullet_finish", from = "loading_bullet",    to = "idle"},
	}

	-- 如果继承类提供了其他事件，则合并
	table.insertTo(defaultEvents, totable(events))

	-- 设计状态机的默认回调
	local defaultCallbacks = {
		
		onleaveloading_bullet = handler(self, self.onLeaveLoading_bullet),
		
		onleavefiring = handler(self, self.onLeaveFiring_),
	}

	-- 如果继承类提供了其他回调，则合并
	table.merge(defaultCallbacks,totable(callbacks))

	EMPlayer.super.ctor(self,properties, defaultEvents, defaultCallbacks)

end



-- 开火
function EMPlayer:fire()
    self:getFSM():doEvent("fire")
    self:getFSM():doEvent("fire_finish", 0.05)
end

function EMPlayer:reload_bullet()
	self:getFSM():doEvent("reload_bullet")
    self:getFSM():doEvent("reload_bullet_finish", 0.1)
end

function EMPlayer:onLeaveLoading_bullet(event)



    local cooldown = tonum(event.args[1])
    if cooldown > 0 then

    	local thz = self 
    	--print(cooldown)

        -- 如果开火后的冷却时间大于 0，则需要等待
        scheduler.performWithDelayGlobal(function()
            

            if thz:getFSM():getState()=="dead" then
        		event.cancel()
        	else
        		event.transition()
        	end
        end, cooldown)
        return "async"
    end
end



function EMPlayer:canFire()
    return self:getFSM():canDoEvent("fire")
end

function EMPlayer:onLeaveFiring_(event)

	

    local cooldown = tonum(event.args[1])
    if cooldown > 0 then

    	local thz = self 
    	--print(cooldown)

        -- 如果开火后的冷却时间大于 0，则需要等待
        scheduler.performWithDelayGlobal(function()

        	if thz:getFSM():getState()=="dead" then
        		event.cancel()
        	else
        		event.transition()
        	end

        end, cooldown)
        return "async"
    end
end

--=view=========================================================================================================
--local PlayerView = import(".EVPlayer")
local EV = import("..EV")

local EVPlayer = class("EVPlayer",EV)

function EVPlayer:ctor(model)

	EVPlayer.super.ctor(self,model)

	local cls = model.class

	--[[通过代理注册事件的好处：可以方便的在视图删除时，清理所有通过该代理注册的事件，
	同时不影响目标对象上注册的其他事件]]
	cc.EventProxy.new(model,self)
		:addEventListener(cls.CHANGE_STATE_EVENT, self.onStateChange_, self)
		:addEventListener(cls.START_EVENT, self.onStart, self)
		:addEventListener(cls.KILL_EVENT, self.onKill, self)

end

function EVPlayer:onStateChange_(event)

end

function EVPlayer:onStart( event )
	print("function EVPlayer:onStart( event )")
	local frames = display.newFrames("hero_fly_%d.png", 1, 2)
	local animation = display.newAnimation(frames, 0.6 / 4)
	self.sprite_:playAnimationForever(animation)

	-- create body
    self.body_ = app.world:createBoxBody(10, 100,150)

    self.body_:setIsSensor(true)
    self.body_:setCollisionType(1)

    -- binding sprite to body
    self.body_:bind(self.sprite_)
    -- set body position
    self.body_:setPosition(event.x, event.y)
end

function EVPlayer:onKill( event )
	local frames = display.newFrames("hero_blowup_%d.png", 1, 4)
	local animation = display.newAnimation(frames, 0.6 / 4)
	
	self.sprite_:playAnimationOnce(animation,false,handler(self, self.removeController))

	audio.playMusic("assets/wechatoldgame/music/game_over.mp3",false)
end

function EVPlayer:removeController()
	self:getParent():removeSelf(true)
end

function EVPlayer:getPlanePosition()
	return self.sprite_:getPositionInCCPoint()
end

function EVPlayer:setPlanePosition( pos )
	if self.body_ then
		self.body_:setPosition(pos.x, pos.y)
	elseif self.sprite_ then
		self.sprite_:setPosition(pos)	
	end
end
--=controller=========================================================================================================
local Bullet1Controller = import(".ECBullet1")
local Bullet2Controller = import(".ECBullet2")

local EC = import("..EC")
local ECPlayer = class("ECPlayer",EC)

function ECPlayer:ctor(x,y)

	ECPlayer.super.ctor(self)

    self.m = EMPlayer.new({id = "player"})

    self.v = EVPlayer.new(self.m)
    :pos(display.left, display.bottom)
    :addTo(self)

    self.m:getFSM():doEvent("start",x,y) 

    -- create touch layer
    self.layer = display.newLayer()
    self.layer:addTouchEventListener(function(event, x, y)
        return self:onTouch(event, x, y)
    end)
    self.layer:setTouchEnabled(true)
    self:addChild(self.layer)

    -- 注册帧事件
    self:addScriptEventListener(cc.Event.ENTER_FRAME, handler(self, self.tick))

    self.target_pos=ccp(0, 0)
    self.bullet_count=3
    self.bullet_2 = 0 
    self.isDead = false
    self.bomb_num = 0


--[[
    -- 在视图清理后，检查模型上注册的事件，看看是否存在内存泄露
    self:addScriptEventListener(cc.Event.CLEANUP, function()
        self.m:getComponent("components.behavior.EventProtocol"):dumpAllEventListeners()
    end)
]]
end



function ECPlayer:onTouch(event,x,y)

	self.target_pos=self:convertToNodeSpace(ccp(x, y))

    if event~="ended" then
        self.isMoving=true
    end

	if event == "began" then
        return true -- 在 began 事件里返回 true，表示要接收后续的触摸事件
    end


    
end



function ECPlayer:tick( dt )

    if self.m:getFSM():getState()=="dead" then
        return
    end

    if self.isMoving==true then

        local speed = 600*dt*2
    
        --计算位置，更新位置
        local current_pos = self.v:getPlanePosition()
        if ccpDistance(self.target_pos, current_pos)<speed then
            self.v:setPlanePosition(self.target_pos)
            self.isMoving=false
        else
            local pos = ccpNormalize(ccpSub(self.target_pos, current_pos))
            local pos_x_speed = ccpMult(pos, speed)
            local target_pos = ccpAdd(current_pos, pos_x_speed)
            self.v:setPlanePosition(target_pos)
        end
    end

    if self.m:canFire() then 
        self:fire()
    end

end

function ECPlayer:fire()

	if self.bullet_count==0 then
		self.m:reload_bullet()
		self.bullet_count=3
		return
	end

    local current_pos = self.v:getPlanePosition()

    self.m:fire()
    self.bullet_count=self.bullet_count-1

    audio.playSound("music/bullet.mp3")

    -- 创建子弹图像，并设置起始位置和飞行方向
 
    --子弹序列

    if self.bullet_2 > 0 then
        self.bullet_2 = self.bullet_2 - 1 
        local bullet = Bullet2Controller.new(current_pos.x,current_pos.y+20):addTo(app.maplayer)
    else
        local bullet = Bullet1Controller.new(current_pos.x,current_pos.y+20):addTo(app.maplayer)
    end

    

end

function ECPlayer:upgrade_bullet()
    self.bullet_2 = self.bullet_2 + 100 
end

function ECPlayer:upgrade_bomb()
    self.bomb_num = self.bomb_num + 1
end

function ECPlayer:be_kill()
    self.m:getFSM():doEventForce("kill") 
    self.isDead = true
end

return ECPlayer